package com.syyo.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.syyo.admin.common.enums.ResultEnum;
import com.syyo.admin.common.exception.SysException;
import com.syyo.admin.domain.ResultVo;
import com.syyo.admin.domain.entity.SysMenu;
import com.syyo.admin.domain.req.MenuReq;
import com.syyo.admin.mapper.SysMenuMapper;
import com.syyo.admin.mapper.SysUserMapper;
import com.syyo.admin.service.SysMenuService;
import com.syyo.admin.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wang
 * @since 2020-07-17
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Autowired
    private SysMenuMapper menuMapper;

    @Autowired
    private SysUserMapper userMapper;

    @Override
    @Transactional
    public ResultVo add(MenuReq req) {
        SysMenu sysMenu = new SysMenu();
        sysMenu.setMenuName(req.getMenuName());

        List<Integer> pidList = req.getPidList();
        Integer pid = MyStringUtils.getPid(pidList);
        String pids = MyStringUtils.getPids(pidList);
        sysMenu.setPid(pid);
        sysMenu.setPids(pids);
        sysMenu.setPerms(req.getPerms());
        sysMenu.setPath(req.getPath());
        sysMenu.setComponent(req.getComponent());
        sysMenu.setComponentName(req.getComponentName());
        sysMenu.setHidden(req.getHidden());
        sysMenu.setCache(req.getCache());
        sysMenu.setIcon(req.getIcon());
        sysMenu.setType(req.getType());
        sysMenu.setSort(req.getSort());
        LocalDateTime now = LocalDateTime.now();
        sysMenu.setCreateTime(now);
        sysMenu.setUpdateTime(now);
        int insert = menuMapper.insert(sysMenu);
        if (insert != 1){
            throw new SysException(ResultEnum.E_80001.getCode(),ResultEnum.E_80001.getMessage());
        }
        return ResultUtils.ok(insert);

    }

    @Override
    @Transactional
    public ResultVo del(MenuReq req) {
        int insert = menuMapper.deleteById(req.getMenuId());
        if (insert != 1){
            throw new SysException(ResultEnum.E_80002.getCode(),ResultEnum.E_80002.getMessage());
        }
        return ResultUtils.ok(insert);
    }

    @Override
    @Transactional
    public ResultVo edit(MenuReq req) {
        SysMenu sysMenu = new SysMenu();
        sysMenu.setMenuId(req.getMenuId());
        sysMenu.setMenuName(req.getMenuName());
        List<Integer> pidList = req.getPidList();

        Integer pid = MyStringUtils.getPid(pidList);
        String pids = MyStringUtils.getPids(pidList);
        sysMenu.setPid(pid);
        sysMenu.setPids(pids);
        sysMenu.setPerms(req.getPerms());
        sysMenu.setPath(req.getPath());
        sysMenu.setComponent(req.getComponent());
        sysMenu.setComponentName(req.getComponentName());
        sysMenu.setHidden(req.getHidden());
        sysMenu.setCache(req.getCache());
        sysMenu.setIcon(req.getIcon());
        sysMenu.setType(req.getType());
        sysMenu.setSort(req.getSort());
        LocalDateTime now = LocalDateTime.now();
        sysMenu.setCreateTime(now);
        int insert = menuMapper.updateById(sysMenu);
        if (insert != 1){
            throw new SysException(ResultEnum.E_80003.getCode(),ResultEnum.E_80003.getMessage());
        }
        return ResultUtils.ok(insert);
    }

    @Override
    public ResultVo findOne(Integer id) {
        SysMenu sysMenu = menuMapper.selectById(id);
        String pids = sysMenu.getPids();
        List<Integer> list = MyStringUtils.stringToList(pids);
        sysMenu.setPidList(list);
        return ResultUtils.ok(sysMenu);
    }

    @Override
    public ResultVo tree() {
        QueryWrapper<SysMenu> wrapper = new QueryWrapper<SysMenu>();
        wrapper.orderByAsc("sort");
        List<SysMenu> list = menuMapper.selectList(wrapper);
        List<SysMenu> menuResps = TreeUtils.listToMenuTree(list);
        return ResultUtils.ok(menuResps);
    }

    @Override
    public ResultVo buildMenu() {
        //根据token 获取对应的菜单，目前只支持3级
        String username = SecurityUtils.getUsername();
        List<Integer> roleIds = userMapper.getRoleIdByUserName(username);
        // 菜单去重
        Set<SysMenu> menuSet= new HashSet<>();
        for (Integer roleId : roleIds) {
            // 查询所有菜单
            Set<SysMenu> menuResps = menuMapper.getMenuByRoleId(roleId);
            for (SysMenu menuResp : menuResps) {
                if (menuResp.getType()==3){
                    //添加2级的菜单
                    SysMenu sysMenu = menuMapper.selectById(menuResp.getPid());
                    menuSet.add(sysMenu);

                    //添加1级的菜单
                    SysMenu sysMenu2 = menuMapper.selectById(sysMenu.getPid());
                    menuSet.add(sysMenu2);
                }else if (menuResp.getType()==2){
                    //添加2级的菜单
                    SysMenu sysMenu = menuMapper.selectById(menuResp.getPid());
                    menuSet.add(sysMenu);
                    menuSet.add(menuResp);
                }
            }
        }

        //转成list 排序
        List<SysMenu> list = new ArrayList<SysMenu> ();
        list.addAll(menuSet);
        Collections.sort(list);
        List<SysMenu> menuResps1 = TreeUtils.listToMenuTree(list);

        //封装前端需要的菜单
        List<Map> maps = menu_digui(menuResps1);
        return ResultUtils.ok(maps);
    }

    private List<Map> menu_digui(List<SysMenu> menuResps1) {
        List<Map> maps = new ArrayList<Map> ();
        for (SysMenu menuResp : menuResps1) {
            Map<String, Object> map = new HashMap<>();
            map.put("name",menuResp.getComponentName());
            map.put("hidden",menuResp.getHidden());
            Map<String, Object> meta = new HashMap<>();
            meta.put("icon",menuResp.getIcon());
            meta.put("title",menuResp.getMenuName());
            meta.put("noCache",menuResp.getCache());
            map.put("meta",meta);
            if (MyStringUtils.isEmpty(menuResp.getComponent())){
                map.put("path","/" + menuResp.getPath());
                map.put("component","Layout");
            }else {
                map.put("path",menuResp.getPath());
                map.put("component",menuResp.getComponent());
            }
            List<SysMenu> children = menuResp.getChildren();
            if (MyListUtils.isNotEmpty(children) && menuResps1.size() != maps.size()){
                List<Map> maps1 = menu_digui(children);
                map.put("children",maps1);
                maps.add(map);
                //递归
            }else if (MyListUtils.isEmpty(children) && menuResps1.size() != maps.size()){
                maps.add(map);
            }else {
                return maps;
            }
        }
        return maps;
    }

}
